/*! ******************************************************************************
 *
 * Created on 2022年3月23日
 *
 * Copyright(c) YuZhou Big Data Laboratory CO.,Ltd, 2022.  All rights reserved.
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/
package org.pentaho.di.ui.core.gui;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.pentaho.di.core.exception.KettleFileException;
import org.pentaho.di.core.logging.LogChannel;
import org.pentaho.di.core.logging.LogChannelInterface;
import org.pentaho.di.core.vfs.KettleVFS;
import org.pentaho.di.ui.core.PropsUI;
import org.yzbdl.lanius.core.constant.LocalDir;

/**
 * @author hs@yzbdl.ac.cn
 *
 */
public class LaniusGuiResource {

    private static LogChannelInterface log = new LogChannel("GUIResource");

    private static LaniusGuiResource guiResource;

    private Display display;

    private Map<String, Image> imageMap;

    private LaniusGuiResource(Display display) {
        this.display = display;
        imageMap = new HashMap<String, Image>();
    }

    public static final LaniusGuiResource getInstance() {
        if (guiResource != null) {
            return guiResource;
        }
        guiResource = new LaniusGuiResource(PropsUI.getDisplay());
        return guiResource;
    }

    /**
     * 获取插件图片
     * 
     * @return
     * @throws Exception
     */
    public Image getPluginImage(String pluginFolder, String version, int size) throws KettleFileException {
        // pluginId_version_sizexsize: excelInput_1.0.0_16x16
        StringBuffer key = new StringBuffer().append(pluginFolder).append("_").append(version).append("_").append(size)
            .append("x").append(size);
        Image image = imageMap.get(key.toString());

        if (image == null) {
            String location = LocalDir.PLUGIN + LocalDir.separator + pluginFolder + LocalDir.separator
                + LocalDir.PLUGIN_ICONS_DIR + LocalDir.separator + size + "x" + size + ".png";
            image = loadFromVFS(display, location);
            imageMap.put(key.toString(), image);
        }
        return image;

    }

    /**
     * 从类路径中读取图片,如果没有则返回空.
     * 
     * @param imageLocation 图片在类路径中的位置
     * @param size
     * @return
     * @throws KettleFileException
     */
    public Image getCpImage(String imageLocation, int width, int height) {
        String key = imageLocation + "_" + width + "x" + height;
        Image image = imageMap.get(key);
        if (image == null) {
            try {
                image = loadFromCurrentClasspath(display, imageLocation);
                Image result = new Image(display, width, height);
                GC gc = new GC(result);
                gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, 0, 0, width, height);
                gc.dispose();
                image = result;
            } catch (Exception e) {
                return null;
            }
            imageMap.put(key, image);
        }
        return image;
    }

    /**
     * 从类路径读取图片,如果没有则返回C3Image.NO_IMAGE对应的图片.
     * 
     * @param imageLocation
     * @param size
     * @return
     */
    public Image getNotNullCpImage(String imageLocation, int width, int height) {
        Image image = getCpImage(imageLocation, width, height);
        if (image == null) {
            image = getCpImage(LaniusImage.NO_IMAGE, width, height);
        }
        return image;
    }

    private Image loadFromVFS(Display display, String location) throws KettleFileException {
        InputStream s = KettleVFS.getInputStream(location);
        try {
            return loadImage(display, s);
        } finally {
            IOUtils.closeQuietly(s);
        }
    }

    private Image loadFromCurrentClasspath(Display display, String location) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        if (cl == null) {
            cl = LaniusGuiResource.class.getClassLoader();
        }
        URL res = null;
        try {
            res = cl.getResource(location);
        } catch (Throwable t) {
            log.logDebug("Unable to load image from classloader [" + location + "]");
        }
        if (res == null) {
            return null;
        }
        InputStream s;
        try {
            s = res.openStream();
        } catch (IOException ex) {
            return null;
        }
        if (s == null) {
            return null;
        }
        try {
            return loadImage(display, s);
        } finally {
            IOUtils.closeQuietly(s);
        }
    }

    private Image loadImage(Display display, InputStream in) {
        return new Image(display, in);
    }

}
